<template>
  <div class="webchatMessageContent">
    <div class="webchatMessageHistory">
      <div class="historyBtn" v-show="showHistoryBtn && loadFlag">
        <span class="more" @click.stop="getMoreHistory">查看历史会话消息</span>
      </div>
      <div class="history_liading" v-show="loadFlag === false">
        <div class="history_liading_text">
          <img src="../../assets/img/webchatLoading.gif" alt=""><span>加载中</span>
        </div>
      </div>
      <div v-for="(item, index) in historyList" :key="index" class="messageItem">
        <!-- 系统消息 -->
        <div v-if="item.type === 'system'" class="system">
          <p>- {{item.content}} -</p>
        </div>
        <!-- 满意度系统消息 -->
        <div v-if="item.type === 'csrInvite'" class="system">
          {{(item.createTime ? item.createTime : '')  + ' ' + item.content}}
        </div>
        <!-- 满意度提交系统消息 -->
        <div v-if="item.type === 'csrSubmit'" class="system">
          {{(item.createTime ? item.createTime : '')  + ' '}}
          <span class="csrSubmit">{{item.content}}</span>
        </div>
        <!-- 非系统消息 -->
        <div v-if="!['system', 'csrInvite', 'csrSubmit'].includes(item.type)">
          <p :class="item.type === 'out' ? 'outBox' : 'inBox'">
            <span v-if="item.type === 'out'" class="name">{{outName(item)}}</span>
            <span v-if="item.type === 'in'" class="name">访客</span>
            {{item.createTime}}
          </p>
          <!-- 文本消息 -->
          <div v-if="item.contentType === 'text'" v-html="item.content" class="content">
          </div>
          <!-- 富文本消息 -->
          <div v-if="item.contentType === 'richText'" v-html="item.content" class="content"></div>
          <!-- 图片消息 -->
          <div v-if="item.contentType === 'image'">
            <img :src="item.content + '?imageView2/2/w/200/h/200'" alt="">
          </div>
          <!-- 语音消息 -->
          <div v-if="item.contentType === 'voice'"
              :class="item.type === 'in' ? 'voiceBox' : ''" @click="playVoice(item)">
            <webchatVoice :chatMsg="item" :sessionId="webchatHistoryInfo.sessionId"></webchatVoice>
          </div>
          <!-- 机器人消息 newPushQues 为机器人分组消息, msgTask 为机器人物流消息)-->
          <div v-if="item.contentType === 'newPushQues' || item.contentType === 'msgTask'"
            v-html="item.content" class="content">
          </div>
          <!-- 微信视频 -->
          <div v-if="item.contentType === 'video'" @click="playVideo(item)" class="videoBox">
            <div class="wechat_video_play_icon">
              <div class="play_icon"></div>
            </div>
            <img v-if="item.thumbPicUrl" :src="doMain + item.thumbPicUrl">
            <div v-else class="videoBoxNoData">
              <div class="thunmbnail_no_icom"></div>
            </div>
          </div>
          <!-- 商品卡片消息 -->
          <div v-if="item.contentType === 'miniprogrampage'" class="cardInfo clearfix">
            <img :src="picUrlHandle(item.miniCardInfo.pictureUrl)" alt="" class="fl">
            <div class="fl cardInfoLeft">
              <div class="cardInfoTitle">
                {{item.miniCardInfo.title}}
              </div>
              <div class="cardInfoFlag">
                <span class="V7_iconfont V7_iconV7tubiao_weixinxiaochengxu"></span>
                微信小程序
              </div>
            </div>
          </div>
          <div v-if="item.contentType === 'orderCardInfo'" class="orderCardInfo clearfix">
            <div>
              <h5>{{item.content.orderTitle || ''}}</h5>
              <p class="orderNum"><span>{{item.content.orderNumName || ''}}</span><span>{{item.content.orderNum || ''}}</span></p>
            </div>
            <template v-if="item.content.orderList && item.content.orderList.length > 0">
              <div v-for="(orderListItem, orderListIndex) in item.content.orderList"
                :key="orderListIndex" class="orderListItem clearfix"
                @click="orderOpen({type: orderListItem.clickTarget || '', url: orderListItem.clickUrl || ''})">
                <img :src="orderListItem.imgUrl || ''" alt="" class="fl">
                <div class="fl orderRight">
                  <div class="orderRightTitle">{{orderListItem.content || ''}}</div>
                  <div class="orderPrice">{{orderListItem.price || ''}}</div>
                </div>
              </div>
            </template>
            <div v-if="item.content.btnRightShow" class="orderBtn fr"
              @click="orderOpen({type: item.content.btnRightTarget || '', url: item.content.btnRightUrl || ''})">
              {{item.content.btnRightText}}
            </div>
            <div v-if="item.content.btnLeftShow" class="orderBtn fr" style="marginRight: 10px"
              @click="orderOpen({type: item.content.btnLeftTarget || '', url: item.content.btnLeftUrl || ''})">
              {{item.content.btnLeftText}}
            </div>
          </div>
          <!-- 文件消息 -->
          <div v-if="item.contentType=== 'file'" class="fileMsg clearfix">
            <div class="clearfix">
              <icon-svg class="fl fileIcon" :iconClass="item | fileIcon"></icon-svg>
              <div class="fl">
                <p class="fileName">{{item.fileName}}</p>
                <p class="fileSize">{{item.fileSize}}
                  <span>/</span>
                  <a :href="item.content" target="_blank" download style="marginLeft: 5px">下载</a>
                </p>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator'
import { msgConvertion } from '@/utils/webchat'
import { filterXSS, deepClone } from '@/utils/common'
import { WebchatModule } from '@/store/modules/webchat'
import webchatVoice from '@/views/webchat/common/webchatVoice.vue'
import { MessageObj, OutNameObj } from '@/views/webchat/webchatInterface'
@Component({
  name: 'webchatMessageHistory',
  components: { webchatVoice },
  filters: {
    fileIcon (item: MessageObj) { // 文件icon处理
      const fileExtension = item.fileName ? item.fileName.split('.').pop().toLowerCase() : ''
      const audio = ['mp3', 'mpeg', 'midi']
      if (audio.includes(fileExtension)) {
        return 'yinle'
      } else if (fileExtension === 'mp4') {
        return 'shipin'
      } else {
        return 'wenjian'
      }
    }
  }
})
export default class WebchatMessageHistory extends Vue {
  @Prop() private webchatHistoryInfo: any
  private $store: any
  private $route: any
  private $bus: any

  private lastPlayTime = 0

  private doMain: string = ''

  private userId: string = ''

  private historyList = []

  private showHistoryBtn = false // 是否展示加载更多按钮

  private finishChatScroll = false // 是否允许滚动加载历史消息

  private loadFlag = true // loading

  private msgBoxScrollTarget: any = -1 // 当前滚动条位置

  private outName (obj: OutNameObj) {
    if (obj.userId === 'robot') {
      return '机器人 '
    } else if (obj.userId === 'system') {
      return '系统 '
    } else {
      return obj.userId === this.userId ? '我 ' : obj.userName
    }
  }

  private picUrlHandle (url: string) {
    const reg = /(http|https):\/\/([\w.]+\/?)\S*/
    return reg.test(url) ? url : this.doMain + url
  }

  private getMoreHistory () { // 获取历史消息事件
    const messageHistoryList: any = deepClone(this.historyList)
    let dateTime = 0
    if (messageHistoryList && messageHistoryList.length > 0) {
      dateTime = messageHistoryList[0].createTimestamp
    }
    this.getHistoryList({ type: 'more', time: dateTime })
  }

  private playVideo (chatMsg: MessageObj) { // 在线播放视频
    const arr = this.$route.path.split('/') || []
    const tabType = arr[3]
    if (tabType === 'webchat_todo') {
      this.$bus.$emit('webchatVideoReplay', { chatMsg })
    } else {
      this.$bus.$emit('webchatDataVideoReplay', { chatMsg })
    }
  }

  private voiceRest (chatMsg: MessageObj) {
    this.historyList.forEach(item => {
      if (!chatMsg.play) {
        Vue.set(item, 'play', false)
      }
    })
  }

  private getHistoryList (data ?: any) {
    let { visitorId, dateTime, _id } = this.webchatHistoryInfo
    if (data && data.type === 'more') {
      dateTime = data.time
    }
    this.$nextTick(() => {
      const chatMsgBoxDom: any = document.getElementsByClassName('webchatMessageHistory')[0]
      this.msgBoxScrollTarget = chatMsgBoxDom.offsetHeight // 获取当前滚动条位置
      const sendData = { visitorId, dateTime, limit: 20, sessionId: _id }
      const actionData = { url: '/im-center/action/webchat/queryHistory', method: 'POST', data: sendData }
      this.loadFlag = false
      const initConfig = (this as any).$store.state.common.initConfig
      WebchatModule.webchatCommonAction(actionData).then(res => {
        if (res) {
          const messageList: any = res.messageList.reverse()
          // 保留当前滚动条位置
          window.setTimeout(() => {
            if (this.msgBoxScrollTarget > -1 && document.getElementsByClassName('webchatMessageContent').length > 0) {
              document.getElementsByClassName('webchatMessageContent')[0].scrollTop = chatMsgBoxDom.scrollHeight - this.msgBoxScrollTarget - 40
              this.msgBoxScrollTarget = -1
            }
            this.loadFlag = true
          }, 0)
          const reg = /(http|https):\/\/([\w.]+\/?)\S*/
          messageList.forEach((obj: MessageObj) => {
            const wordsSetting: any = this.$store.state.common.publicCache.globalConfig[0] || {}
            if (obj.type === 'in') {
              if (wordsSetting) {
                // 访客敏感词是否开启，是否有敏感词
                if (wordsSetting.visitorSensitiveWordsFlag && wordsSetting.visitorSensitiveWords) {
                  const visitorSensitiveWords = wordsSetting.visitorSensitiveWords.split(',')
                  if (visitorSensitiveWords && visitorSensitiveWords.length > 0) {
                    for (let i = 0; i < visitorSensitiveWords.length; i++) {
                      const replaceString = '**'
                      obj.content = obj.content.replace(RegExp(visitorSensitiveWords[i], 'g'), replaceString);
                    }
                  }
                }
                // 判断访客关键词是否开启，是否有关键词
                if (wordsSetting.visitorFocusWordsFlag && wordsSetting.visitorFocusWords) {
                  const visitorFocusWords = wordsSetting.visitorFocusWords.split(',')
                  if (visitorFocusWords && visitorFocusWords.length > 0) {
                    for (let i = 0; i < visitorFocusWords.length; i++) {
                      const replaceString = '<span style="color: ' + wordsSetting.visitorFocusWordsColor + ';">' + visitorFocusWords[i] + '</span>'
                      obj.content = obj.content.replace(RegExp(visitorFocusWords[i], 'g'), replaceString);
                    }
                  }
                }
              }
            }
            if (obj.type === 'out') {
              if (wordsSetting) {
                // 座席敏感词是否开启，是否有敏感词
                if (wordsSetting.agentSensitiveWordsFlag && wordsSetting.agentSensitiveWords) {
                  const agentSensitiveWords = wordsSetting.agentSensitiveWords.split(',')
                  if (agentSensitiveWords && agentSensitiveWords.length > 0) {
                    for (let i = 0; i < agentSensitiveWords.length; i++) {
                      const replaceString = '**'
                      obj.content = obj.content.replace(RegExp(agentSensitiveWords[i], 'g'), replaceString);
                    }
                  }
                }
                // 座席关键词是否开启，是否有关键词
                if (wordsSetting.agentFocusWordsFlag && wordsSetting.agentFocusWords) {
                  const agentFocusWords = wordsSetting.agentFocusWords.split(',')
                  if (agentFocusWords && agentFocusWords.length > 0) {
                    for (let i = 0; i < agentFocusWords.length; i++) {
                      const replaceString = '<span style="color: ' + wordsSetting.agentFocusWordsColor + ';">' + agentFocusWords[i] + '</span>'
                      obj.content = obj.content.replace(RegExp(agentFocusWords[i], 'g'), replaceString);
                    }
                  }
                }
              }
            }
            if (obj.contentType === 'text' || obj.contentType === 'newPushQues' || obj.contentType === 'msgTask') {
              obj.content = msgConvertion(obj.content) // 处理文本类型超链接
            } else if (obj.contentType === 'voice') {
              Vue.set(obj, 'play', false)
            }
            if (obj.contentType === 'image' || obj.contentType === 'file') { // 图片和文件域名拼接
              if (!reg.test(obj.content)) {
                obj.content = initConfig ? initConfig.qiniuDomainMap.im + obj.content : ''
              }
            }
            if (obj.content.indexOf('&lt;7moorbr/&gt;') > -1 || obj.content.indexOf('<7moorbr/>') > -1) {
              obj.content = obj.content.replace(/<7moorbr\/>/g, '<br />')
              obj.content = obj.content.replace(/&lt;7moorbr\/&gt;/g, '<br />')
            }
            // 会话消息，回显的时候，回车没有替换成br处理
            obj.content = obj.content.replace(/[\n\r]/g, '<br />')
            obj.content = filterXSS(obj.content)
            if (obj.contentType === 'orderCardInfo' && obj.content) { // 订单消息处理
              try {
                obj.content = JSON.parse(decodeURIComponent(obj.content))
              } catch (e) {
                obj.content = JSON.parse(obj.content)
              }
            }
          })
          this.handleMessageList(messageList)
          this.loadFlag = true
        }
      })
    })
  }

  private handleMessageList (messageList: any) {
    this.historyList = messageList.concat(this.historyList)
    if (messageList.length >= 20) {
      // 查询的是当前会话记录，且大于等于20条，展示查询历史的按钮
      this.showHistoryBtn = true
      this.finishChatScroll = true
    } else {
      this.showHistoryBtn = false
      this.finishChatScroll = false
    }
  }

  private playVoice (chatMsg: MessageObj) { // 播放语音
    const currentTime = Date.now()
    if ((currentTime - this.lastPlayTime) < 300) {
      return
    }
    this.voiceRest(chatMsg)
    this.historyList.forEach((item: any) => {
      if (item.createTimestamp === chatMsg.createTimestamp) {
        if (!chatMsg.play) {
          Vue.set(item, 'play', true)
        } else {
          Vue.set(item, 'play', false)
        }
      }
    })
    this.lastPlayTime = Date.now()
  }

  private mounted () {
    const initConfig = this.$store.state.common.initConfig
    const user = this.$store.state.common.session.user
    const doMain = initConfig && initConfig.qiniuDomainMap ? initConfig.qiniuDomainMap.im : '' // 公共域名
    this.doMain = doMain
    this.userId = user && user._id ? user._id : '' // 此座席id
    this.getHistoryList()
  }
}
</script>
<style lang="stylus" scoped>
  .webchatMessageHistory
    height 293px
    overflow-y auto
    .historyBtn
      text-align center
      margin 16px 0px 19px 0px
      .more
        color #008BEE
        cursor pointer
    .history_liading
      margin-top 5px
      text-align center
      .history_liading_text
        color #000
        display inline-block
        &:after
          display inline-block
          width 0
          height 100%
          content 'center'
          vertical-align middle
          overflow hidden
        img
          vertical-align middle
    .messageItem
      margin 10px 0px
      .system
        text-align center
        color #BABECB
      .csrSubmit
        color #008BEE
        text-overflow ellipsis
        white-space nowrap
        overflow hidden
        max-width calc(100% - 50px)
        display inline-block
        vertical-align bottom
      .outBox
        color #008BEE
      .inBox
        color #686E84
      .content
        color #303753
        margin-top 4px
        line-height 25px
        .robotImage
          width 100%
      .voiceBox
        background-color #ffffff
        width 100px
        border-radius 10px
      .videoBox
        max-width 200px
        max-height 200px
        position relative
        cursor pointer
        img
          border-radius 10px
          max-height 200px
        .wechat_video_play_icon
          position absolute
          width 50%
          height 100%
        .play_icon
          position absolute
          width 26px
          height 26px
          margin -13px 0 0 -13px
          top 50%
          left 50%
          background url('../../assets/img/play_icon.png') no-repeat
          z-index 2
          background-size 100%
      .videoBoxNoData
        border-radius 10px
        height 150px
        width 200px
        background-color #b7b7b7
      .cardInfo
        width 250px
        padding 14px
        border 1px solid $border-main
        border-radius 10px
        background #fff
        img
          height 68px
          width 68px
          border-radius 4px
          margin-right 14px
        .cardInfoLeft
          width 130px
          .cardInfoTitle
            text-align left
            line-height 1.5em
            color #303753
            text-overflow ellipsis
            display -webkit-box
            -webkit-line-clamp 2
            -webkit-box-orient vertical
            overflow hidden
            margin-bottom 14px
          .cardInfoFlag
            color #767E91
            padding-top 10px
            border-top 1px solid $border-main
            .V7_iconV7tubiao_weixinxiaochengxu
              color #7587D8
              visibility middle
      .orderCardInfo
        width 250px
        padding 14px
        border 1px solid $border-main
        border-radius 10px
        background #fff
        .orderNum
          padding 6px 0px
          border-bottom 1px solid $border-main
          color #767E91
          span
            margin-right 4px
        .orderListItem
          margin-top 6px
          cursor pointer
          img
            width 52px
            height 52px
            border 1px solid $border-main
            border-radius 4px
          .orderRight
            width 150px
            margin-left 10px
            .orderRightTitle
              text-align left
              line-height 1.5em
              color #303753
              text-overflow ellipsis
              display -webkit-box
              -webkit-line-clamp 2
              -webkit-box-orient vertical
              overflow hidden
              margin-bottom 6px
            .orderPrice
              color #FC6B5C
        .orderBtn
          width 70px
          height 24px
          line-height 24px
          text-align center
          border 1px solid $border-main
          border-radius 12px
          margin-top 15px
          cursor pointer
      .fileMsg
        background-color white
        border 1px solid $border-main
        padding 10px
        border-radius 10px
        max-width 300px
        position relative
        .fileIcon
          display inline-block
          font-size 36px
          text-align center
          border-radius 4px
          margin 10px 11px 0px 0px
        .V7_iconV7tubiao_yinle
          color #53B192
        .V7_iconV7tubiao_shipin
          color #BF6CF7
        .fileName
          margin-top 10px
          max-width 180px
          color #303753
          font-size 14px
          text-overflow ellipsis
          overflow hidden
          white-space nowrap
        .fileSize
          color #b3b9c7
</style>
